﻿//////////////////////////////////////////////////////////////////////////////
//
// Copyright © 1998-2024 Glodon Company Limited.
//
// Licensed under the MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the “Software”),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//////////////////////////////////////////////////////////////////////////////
#include "StructureInstanceCmdUtils.h"
#include "GbmpBuiltInParameterDefinitionsNew.h"
#include "GbmpBuiltInParameterStaticVauleListItems.h"
#include "GbmpModelViewUtil.h"
#include "GcmpBuiltInParameterDefinitions.h"
#include "IDocument.h"
#include "IFamilyType.h"
#include "IGbmpElevationView.h"
#include "IModelLine.h"
#include "IParameter.h"
#include "IParameterDefinitionLibrary.h"
#include "IRadioButtonGroupDefinition.h"
#include "LevelUtils.h"
#include "LineFamilyPositionCurveSideType.h"
#include "MathUtils.h"
#include "StructureBeamInput.h"
#include "StructureColumnInput.h"
#include "StructureInstanceEndType.h"
#include "StructureInstancePresetParameterUtils.h"
#include "StructurePlateHoleInput.h"
#include "StructureProfileInstanceInput.h"
#include "StructureRoofInput.h"
#include "StructureStripFoundationInput.h"
#include "StructureWallHoleInput.h"
#include "StructureWallInput.h"

#include "EnableCompileWarning_The_LAST_IncludeInCpp.h"

using namespace gcmp;

namespace
{
    std::wstring s_PositionLeft = GBMP_TR(L"左侧");
    std::wstring s_PositionCenter = GBMP_TR(L"中心");
    std::wstring s_PositionRight = GBMP_TR(L"右侧");
}

bool StructureInstanceCmdUtils::GenerateStraightBasicBeamInput(IDocument* pDoc, IModelView* pModelView,
    const UniIdentity& category, Int32 categorySecondKey, ElementId familyId, ElementId instanceTypeId,
    StructureBeamInput& input)
{
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pDoc, L"pDoc为空",L"GDMPLab",L"2024-03-30");
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pModelView, L"pModelView为空",L"GDMPLab",L"2024-03-30");
    ElementId storyId = ElementId::InvalidID;
    StructureInstancePresetParameterUtils::GetPresetStoryLevel(pDoc, category, categorySecondKey, storyId);
    input.StoreyId = storyId;

    ElementId associatedPlaneId = GbmpModelViewUtil::GetWorkLevelId(pModelView);
    StructureInstancePresetParameterUtils::GetPresetTopLevel(pDoc, category, categorySecondKey, associatedPlaneId);
    DBG_WARN_AND_RETURN_FALSE_UNLESS(associatedPlaneId.IsValid(), L"associatedPlaneId无效",L"GDMPLab",L"2024-03-30");

    input.Document = pDoc;
    input.AssociatedPlaneId = associatedPlaneId;
    input.FamilyId = familyId;
    input.InstanceTypeId = instanceTypeId;
    input.categoryUid = category;

    double topOffset(0);
    StructureInstancePresetParameterUtils::GetPresetTopLevelOffset(pDoc, category, categorySecondKey, topOffset);
    double startOffset(0);
    StructureInstancePresetParameterUtils::GetPresetStartOffset(pDoc, category, categorySecondKey, startOffset);
    double endOffset(0);
    StructureInstancePresetParameterUtils::GetPresetEndOffset(pDoc, category, categorySecondKey, endOffset);
    input.AssociatedPlaneOffset = topOffset;
    input.StartOffset = startOffset;
    input.EndOffset = endOffset;

    BeamZPositioningType zPositioningType(BeamZPositioningType::Top);
    StructureInstancePresetParameterUtils::GetPresetZPositioningType(pDoc, category, categorySecondKey, zPositioningType);
    input.ZPositioningType = zPositioningType;

    ConcreteStrengthGradeType concreteType(ConcreteStrengthGradeType::CSG_C30);
    StructureInstancePresetParameterUtils::GetPresetConcreteStrengthGradeType(pDoc, category, categorySecondKey, concreteType);
    input.ConcreteType = concreteType;

    input.StartEndFaceSectionType = InstanceEndType::Vertical;

    return true;
}

bool StructureInstanceCmdUtils::GenerateStraightVariableSectionBeamInput(IDocument* pDoc, IModelView* pModelView,
    const UniIdentity& category, Int32 categorySecondKey, ElementId familyId, ElementId instanceTypeId,
    StructureBeamInput& input)
{
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pDoc, L"pDoc为空",L"GDMPLab",L"2024-03-30");
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pModelView, L"pModelView为空",L"GDMPLab",L"2024-03-30");

    ElementId storyId = ElementId::InvalidID;
    StructureInstancePresetParameterUtils::GetPresetStoryLevel(pDoc, category, categorySecondKey, storyId);
    input.StoreyId = storyId;

    ElementId associatedPlaneId = GbmpModelViewUtil::GetWorkLevelId(pModelView);
    StructureInstancePresetParameterUtils::GetPresetTopLevel(pDoc, category, categorySecondKey, associatedPlaneId);
    DBG_WARN_AND_RETURN_FALSE_UNLESS(associatedPlaneId.IsValid(), L"associatedPlaneId无效",L"GDMPLab",L"2024-03-30");

    input.Document = pDoc;
    input.AssociatedPlaneId = associatedPlaneId;
    input.FamilyId = familyId;
    input.InstanceTypeId = instanceTypeId;
    input.categoryUid = category;

    double topOffset(0);
    StructureInstancePresetParameterUtils::GetPresetTopLevelOffset(pDoc, category, categorySecondKey, topOffset);
    input.AssociatedPlaneOffset = topOffset;

    ConcreteStrengthGradeType concreteType(ConcreteStrengthGradeType::CSG_C30);
    StructureInstancePresetParameterUtils::GetPresetConcreteStrengthGradeType(pDoc, category, categorySecondKey, concreteType);
    input.ConcreteType = concreteType;

    return true;
}

bool StructureInstanceCmdUtils::GenerateArcBy3PtsBasicBeamInput(IDocument* pDoc, IModelView* pModelView,
    const UniIdentity& category, Int32 categorySecondKey, ElementId familyId, ElementId instanceTypeId,
    StructureBeamInput& input)
{
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pDoc, L"pDoc为空",L"GDMPLab",L"2024-03-30");
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pModelView, L"pModelView为空",L"GDMPLab",L"2024-03-30");

    ElementId storyId = ElementId::InvalidID;
    StructureInstancePresetParameterUtils::GetPresetStoryLevel(pDoc, category, categorySecondKey, storyId);
    input.StoreyId = storyId;

    ElementId associatedPlaneId = GbmpModelViewUtil::GetWorkLevelId(pModelView);
    StructureInstancePresetParameterUtils::GetPresetTopLevel(pDoc, category, categorySecondKey, associatedPlaneId);
    DBG_WARN_AND_RETURN_FALSE_UNLESS(associatedPlaneId.IsValid(), L"associatedPlaneId无效",L"GDMPLab",L"2024-03-30");

    input.Document = pDoc;
    input.AssociatedPlaneId = associatedPlaneId;
    input.FamilyId = familyId;
    input.InstanceTypeId = instanceTypeId;
    input.categoryUid = category;

    double topOffset(0);
    StructureInstancePresetParameterUtils::GetPresetTopLevelOffset(pDoc, category, categorySecondKey, topOffset);
    input.AssociatedPlaneOffset = topOffset;

    BeamZPositioningType zPositioningType(BeamZPositioningType::Top);
    StructureInstancePresetParameterUtils::GetPresetZPositioningType(pDoc, category, categorySecondKey, zPositioningType);
    input.ZPositioningType = zPositioningType;

    ConcreteStrengthGradeType concreteType(ConcreteStrengthGradeType::CSG_C30);
    StructureInstancePresetParameterUtils::GetPresetConcreteStrengthGradeType(pDoc, category, categorySecondKey, concreteType);
    input.ConcreteType = concreteType;

    return true;
}

bool gcmp::StructureInstanceCmdUtils::GenerateBasicWallInput(IDocument* pDoc, IModelView* pModelView, const UniIdentity& category, Int32 categorySecondKey, ElementId familyId, ElementId instanceTypeId, StructureWallInput& input)
{
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pDoc, L"pDoc为空",L"GDMPLab",L"2024-03-30");
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pModelView, L"pModelView为空",L"GDMPLab",L"2024-03-30");

    ElementId storyId = ElementId::InvalidID;
    StructureInstancePresetParameterUtils::GetPresetStoryLevel(pDoc, category, categorySecondKey, storyId);
    input.StoreyId = storyId;

    input.Document = pDoc;
    input.FamilyId = familyId;
    input.InstanceTypeId = instanceTypeId;
    input.categoryUid = category;

    ElementId associatedPlaneId = GbmpModelViewUtil::GetWorkLevelId(pModelView);
    StructureInstancePresetParameterUtils::GetPresetBaseLevel(pDoc, category, categorySecondKey, associatedPlaneId);
    DBG_WARN_AND_RETURN_FALSE_UNLESS(associatedPlaneId.IsValid(), L"associatedPlaneId无效",L"GDMPLab",L"2024-03-30");
    input.AssociatedPlaneId = associatedPlaneId;

    ElementId topPlaneId = ElementId::InvalidID;
    StructureInstancePresetParameterUtils::GetPresetTopLevel(pDoc, category, categorySecondKey, topPlaneId);
    if (topPlaneId.IsValid())
    {
        ILevel* pTopLevel = LevelUtils::GetLevelById(pDoc, topPlaneId);
        DBG_WARN_AND_RETURN_FALSE_UNLESS(pTopLevel, L"pTopLevel为空",L"GDMPLab",L"2024-03-30");

        ILevel* pBottomLevel = LevelUtils::GetLevelById(pDoc, associatedPlaneId);
        DBG_WARN_AND_RETURN_FALSE_UNLESS(pBottomLevel, L"pBottomLevel为空",L"GDMPLab",L"2024-03-30");

        double topLevelElevation = pTopLevel->GetElevation();
        double bottomLevelElevation = pBottomLevel->GetElevation();
        if (MathUtils::IsLessThan(bottomLevelElevation,topLevelElevation))
        {
            input.TopAssociatedPlaneId = topPlaneId;
        }
    }

    double topLevelOffset(0);
    StructureInstancePresetParameterUtils::GetPresetTopLevelOffset(pDoc, category, categorySecondKey, topLevelOffset);
    input.TopPlaneOffset = topLevelOffset;

    double baseLevelOffset(0);
    StructureInstancePresetParameterUtils::GetPresetBaseLevelOffset(pDoc, category, categorySecondKey, baseLevelOffset);
    input.AssociatedPlaneOffset = baseLevelOffset;

    double wallHeight(3000);
    StructureInstancePresetParameterUtils::GetPresetWallHeight(pDoc, category, categorySecondKey, wallHeight);
    input.WallHeight = wallHeight;

    ConcreteStrengthGradeType concreteType(ConcreteStrengthGradeType::CSG_C30);
    StructureInstancePresetParameterUtils::GetPresetConcreteStrengthGradeType(pDoc, category, categorySecondKey, concreteType);
    input.ConcreteType = concreteType;

    return true;
}

bool gcmp::StructureInstanceCmdUtils::GenerateStraightVariableSectionWallInput(IDocument* pDoc, IModelView* pModelView, const UniIdentity& category, Int32 categorySecondKey, ElementId familyId, ElementId instanceTypeId, StructureWallInput& input)
{
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pDoc, L"pDoc为空",L"GDMPLab",L"2024-03-30");
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pModelView, L"pModelView为空",L"GDMPLab",L"2024-03-30");

    ElementId storyId = ElementId::InvalidID;
    StructureInstancePresetParameterUtils::GetPresetStoryLevel(pDoc, category, categorySecondKey, storyId);
    input.StoreyId = storyId;

    ElementId associatedPlaneId = GbmpModelViewUtil::GetWorkLevelId(pModelView);
    StructureInstancePresetParameterUtils::GetPresetBaseLevel(pDoc, category, categorySecondKey, associatedPlaneId);
    DBG_WARN_AND_RETURN_FALSE_UNLESS(associatedPlaneId.IsValid(), L"associatedPlaneId无效",L"GDMPLab",L"2024-03-30");

    ElementId topPlaneId = ElementId::InvalidID;
    StructureInstancePresetParameterUtils::GetPresetTopLevel(pDoc, category, categorySecondKey, topPlaneId);

    input.Document = pDoc;
    input.AssociatedPlaneId = associatedPlaneId;
    input.TopAssociatedPlaneId = topPlaneId;
    input.FamilyId = familyId;
    input.InstanceTypeId = instanceTypeId;
    input.categoryUid = category;

    double startOffset(0);
    StructureInstancePresetParameterUtils::GetPresetWallStartOffset(pDoc, category, categorySecondKey, startOffset);
    input.StartOffset = startOffset;

    double endOffset(0);
    StructureInstancePresetParameterUtils::GetPresetWallEndOffest(pDoc, category, categorySecondKey, endOffset);
    input.EndOffset = endOffset;

    double startHeight(2000);
    StructureInstancePresetParameterUtils::GetPresetWallStartHeight(pDoc, category, categorySecondKey, startHeight);
    input.StartHeight = startHeight;

    double endHeight(2500);
    StructureInstancePresetParameterUtils::GetPresetWallEndHeight(pDoc, category, categorySecondKey, endHeight);
    input.EndHeight = endHeight;

    ConcreteStrengthGradeType concreteType(ConcreteStrengthGradeType::CSG_C30);
    StructureInstancePresetParameterUtils::GetPresetConcreteStrengthGradeType(pDoc, category, categorySecondKey, concreteType);
    input.ConcreteType = concreteType;

    return true;
}

bool StructureInstanceCmdUtils::GenerateVerticalColumnInput(IDocument* pDoc, IModelView* pModelView,
    const UniIdentity& category, Int32 categorySecondKey, ElementId familyId, ElementId instanceTypeId,
    StructureColumnInput& input)
{
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pDoc, L"pDoc为空",L"GDMPLab",L"2024-03-30");
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pModelView, L"pModelView为空",L"GDMPLab",L"2024-03-30");

    ElementId storyId = ElementId::InvalidID;
    StructureInstancePresetParameterUtils::GetPresetStoryLevel(pDoc, category, categorySecondKey, storyId);
    input.StoreyId = storyId;

    input.Document = pDoc;
    input.FamilyId = familyId;
    input.InstanceTypeId = instanceTypeId;

    ElementId associatedPlaneId = GbmpModelViewUtil::GetWorkLevelId(pModelView);
    StructureInstancePresetParameterUtils::GetPresetBaseLevel(pDoc, category, categorySecondKey, associatedPlaneId);
    DBG_WARN_AND_RETURN_FALSE_UNLESS(associatedPlaneId.IsValid(), L"associatedPlaneId无效",L"GDMPLab",L"2024-03-30");
    input.AssociatedPlaneId = associatedPlaneId;

    ElementId topAssociatedPlaneId = ElementId::InvalidID;
    StructureInstancePresetParameterUtils::GetPresetTopLevel(pDoc, category, categorySecondKey, topAssociatedPlaneId);
    if (topAssociatedPlaneId.IsValid())
    {
        ILevel* pTopLevel = LevelUtils::GetLevelById(pDoc, topAssociatedPlaneId);
        DBG_WARN_AND_RETURN_FALSE_UNLESS(pTopLevel, L"pTopLevel为空",L"GDMPLab",L"2024-03-30");

        ILevel* pBottomLevel = LevelUtils::GetLevelById(pDoc, associatedPlaneId);
        DBG_WARN_AND_RETURN_FALSE_UNLESS(pBottomLevel, L"pBottomLevel为空",L"GDMPLab",L"2024-03-30");

        double topLevelElevation = pTopLevel->GetElevation();
        double bottomLevelElevation = pBottomLevel->GetElevation();
        if (MathUtils::IsLessThan(bottomLevelElevation, topLevelElevation))
        {
            input.TopAssociatedPlaneId = topAssociatedPlaneId;
        }
    }

    double bottomOffset(0);
    StructureInstancePresetParameterUtils::GetPresetBaseLevelOffset(pDoc, category, categorySecondKey, bottomOffset);
    input.AssociatedPlaneOffset = bottomOffset;

    double topOffset(0);
    StructureInstancePresetParameterUtils::GetPresetTopLevelOffset(pDoc, category, categorySecondKey, topOffset);
    input.TopOffset = topOffset;

    ConcreteStrengthGradeType concreteType(ConcreteStrengthGradeType::CSG_C30);
    StructureInstancePresetParameterUtils::GetPresetConcreteStrengthGradeType(pDoc, category, categorySecondKey, concreteType);
    input.ConcreteType = concreteType;

    double height(input.Height);
    StructureInstancePresetParameterUtils::GetPreSetColumnHeight(pDoc, category, categorySecondKey, height);
    input.Height = height;

    return true;
}

bool StructureInstanceCmdUtils::GenerateSlantedColumnInput(IDocument* pDoc, IModelView* pModelView,
    const UniIdentity& category, Int32 categorySecondKey, ElementId familyId, ElementId instanceTypeId,
    StructureColumnInput& input)
{
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pDoc, L"pDoc为空",L"GDMPLab",L"2024-03-30");
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pModelView, L"pModelView为空",L"GDMPLab",L"2024-03-30");

    ElementId storyId = ElementId::InvalidID;
    StructureInstancePresetParameterUtils::GetPresetStoryLevel(pDoc, category, categorySecondKey, storyId);
    input.StoreyId = storyId;

    input.Document = pDoc;
    input.FamilyId = familyId;
    input.InstanceTypeId = instanceTypeId;

    ElementId associatedPlaneId = GbmpModelViewUtil::GetWorkLevelId(pModelView);
    StructureInstancePresetParameterUtils::GetPresetBaseLevel(pDoc, category, categorySecondKey, associatedPlaneId);
    DBG_WARN_AND_RETURN_FALSE_UNLESS(associatedPlaneId.IsValid(), L"associatedPlaneId无效",L"GDMPLab",L"2024-03-30");
    input.AssociatedPlaneId = associatedPlaneId;

    ElementId topAssociatedPlaneId = ElementId::InvalidID;
    StructureInstancePresetParameterUtils::GetPresetTopLevel(pDoc, category, categorySecondKey, topAssociatedPlaneId);
    if (topAssociatedPlaneId.IsValid())
    {
        ILevel* pTopLevel = LevelUtils::GetLevelById(pDoc, topAssociatedPlaneId);
        DBG_WARN_AND_RETURN_FALSE_UNLESS(pTopLevel, L"pTopLevel为空",L"GDMPLab",L"2024-03-30");

        ILevel* pBottomLevel = LevelUtils::GetLevelById(pDoc, associatedPlaneId);
        DBG_WARN_AND_RETURN_FALSE_UNLESS(pBottomLevel, L"pBottomLevel为空",L"GDMPLab",L"2024-03-30");

        double topLevelElevation = pTopLevel->GetElevation();
        double bottomLevelElevation = pBottomLevel->GetElevation();
        if (MathUtils::IsLessThan(bottomLevelElevation, topLevelElevation))
        {
            input.TopAssociatedPlaneId = topAssociatedPlaneId;
        }
    }
    double bottomOffset(0);
    StructureInstancePresetParameterUtils::GetPresetBaseLevelOffset(pDoc, category, categorySecondKey, bottomOffset);
    input.AssociatedPlaneOffset = bottomOffset;

    double topOffset(0);
    StructureInstancePresetParameterUtils::GetPresetTopLevelOffset(pDoc, category, categorySecondKey, topOffset);
    input.TopOffset = topOffset;

    ConcreteStrengthGradeType concreteType(ConcreteStrengthGradeType::CSG_C30);
    StructureInstancePresetParameterUtils::GetPresetConcreteStrengthGradeType(pDoc, category, categorySecondKey, concreteType);
    input.ConcreteType = concreteType;

    InstanceEndType topEndType = InstanceEndType::PerpendicularToAxis;
    InstanceEndType bottomEndType = InstanceEndType::PerpendicularToAxis;
    StructureInstancePresetParameterUtils::GetPresetSlantedColumnTopFaceEndType(pDoc, category, categorySecondKey, topEndType);
    StructureInstancePresetParameterUtils::GetPresetSlantedColumnBottomFaceEndType(pDoc, category, categorySecondKey, bottomEndType);
    input.TopFaceEndType = topEndType;
    input.BottomFaceEndType = bottomEndType;

    double height(input.Height);
    StructureInstancePresetParameterUtils::GetPreSetColumnHeight(pDoc, category, categorySecondKey, height);
    input.Height = height;

    double rotateAngle(input.RotateAngle);
    StructureInstancePresetParameterUtils::GetPresetSlantedColumnSectionRotateAngle(pDoc, category, categorySecondKey, rotateAngle);
    input.RotateAngle = rotateAngle;

    return true;
}

bool gcmp::StructureInstanceCmdUtils::GenerateStructurePlateInput(IDocument* pDoc, IModelView* pModelView, const UniIdentity& category, Int32 categorySecondKey, ElementId familyId, ElementId instanceTypeId, StructureProfileInstanceElementInput& input)
{
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pDoc, L"pDoc为空",L"GDMPLab",L"2024-03-30");
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pModelView, L"pModelView为空",L"GDMPLab",L"2024-03-30");

    ElementId storyId = ElementId::InvalidID;
    StructureInstancePresetParameterUtils::GetPresetStoryLevel(pDoc, category, categorySecondKey, storyId);
    input.StoreyId = storyId;

    ElementId associatedPlaneId = GbmpModelViewUtil::GetWorkLevelId(pModelView);
    StructureInstancePresetParameterUtils::GetPresetTopLevel(pDoc, category, categorySecondKey, associatedPlaneId);
    DBG_WARN_AND_RETURN_FALSE_UNLESS(associatedPlaneId.IsValid(), L"associatedPlaneId无效",L"GDMPLab",L"2024-03-30");

    input.Document = pDoc;
    input.AssociatedPlaneId = associatedPlaneId;
    input.FamilyId = familyId;
    input.InstanceTypeId = instanceTypeId;

    double topOffset(0);
    StructureInstancePresetParameterUtils::GetPresetTopLevelOffset(pDoc, category, categorySecondKey, topOffset);
    input.AssociatedPlaneOffset = topOffset;

    ConcreteStrengthGradeType concreteType(ConcreteStrengthGradeType::CSG_C30);
    StructureInstancePresetParameterUtils::GetPresetConcreteStrengthGradeType(pDoc, category, categorySecondKey, concreteType);
    input.ConcreteType = concreteType;

    return true;
}

bool gcmp::StructureInstanceCmdUtils::GenerateRaftFoundationInput(IDocument* pDoc, IModelView* pModelView, const UniIdentity& category, Int32 categorySecondKey, ElementId familyId, ElementId instanceTypeId, StructureRaftFoundationElementInput& input)
{
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pDoc, L"pDoc为空",L"GDMPLab",L"2024-03-30");
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pModelView, L"pModelView为空",L"GDMPLab",L"2024-03-30");

    ElementId storyId = ElementId::InvalidID;
    StructureInstancePresetParameterUtils::GetPresetStoryLevel(pDoc, category, categorySecondKey, storyId);
    input.StoreyId = storyId;

    bool bOk = StructureInstanceCmdUtils::GenerateStructurePlateInput(pDoc, pModelView, category, categorySecondKey, familyId, instanceTypeId, input);
    DBG_WARN_AND_RETURN_FALSE_UNLESS(bOk, L"创建板型结构输入数据失败",L"GDMPLab",L"2024-03-30");

    //设置Z轴定位位置
    RaftFoundationZPositioningType zPositioningType(RaftFoundationZPositioningType::Top);
    StructureInstancePresetParameterUtils::GetPresetZPositioningType(pDoc, category, categorySecondKey, zPositioningType);
    input.ZPositioningType = zPositioningType;

    return true;
}

bool StructureInstanceCmdUtils::GenerateStructurePlateHoleInput(IDocument* pDoc, IModelView* pModelView,
    const UniIdentity& category, Int32 categorySecondKey, ElementId familyId, ElementId instanceTypeId,
    StructurePlateHoleElementInput& input)
{
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pDoc, L"pDoc为空",L"GDMPLab",L"2024-03-30");
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pModelView, L"pModelView为空",L"GDMPLab",L"2024-03-30");

    ElementId storyId = ElementId::InvalidID;
    StructureInstancePresetParameterUtils::GetPresetStoryLevel(pDoc, category, categorySecondKey, storyId);
    input.StoreyId = storyId;

    ElementId associatedPlaneId = GbmpModelViewUtil::GetWorkLevelId(pModelView);
    StructureInstancePresetParameterUtils::GetPresetTopLevel(pDoc, category, categorySecondKey, associatedPlaneId);
    DBG_WARN_AND_RETURN_FALSE_UNLESS(associatedPlaneId.IsValid(), L"associatedPlaneId无效",L"GDMPLab",L"2024-03-30");

    input.Document = pDoc;
    input.AssociatedPlaneId = associatedPlaneId;
    input.FamilyId = familyId;
    input.InstanceTypeId = instanceTypeId;

    return true;
}

bool StructureInstanceCmdUtils::GenerateStructureWallHoleInput(IDocument* pDoc, const IModelView* pModelView,
    const UniIdentity& category, Int32 categorySecondKey, ElementId familyId, ElementId instanceTypeId,
    StructureWallHoleInput& input)
{
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pDoc, L"pDoc为空",L"GDMPLab",L"2024-03-30");
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pModelView, L"pModelView为空",L"GDMPLab",L"2024-03-30");

    ElementId associatedPlaneId;
    StructureInstancePresetParameterUtils::GetPresetBaseLevel(pDoc, category, categorySecondKey, associatedPlaneId);
    if (!associatedPlaneId.IsValid())
    {
        //TODO：等待立面视图的工作楼层完善
        const IGbmpModelView* pGbmpModelView = GbmpModelViewUtil::GetGbmpModelView(pModelView);
        if (dynamic_cast<const IGbmpElevationView*>(pGbmpModelView))
        {
            std::vector<const ILevel*> levels = LevelUtils::GetStoreyLevelsFromLowToHigh(pDoc);
            DBG_WARN_AND_RETURN_NULLPTR_UNLESS(!levels.empty(), L"没有一个标高",L"GDMPLab",L"2024-03-30");
            associatedPlaneId = levels.front()->GetOwnerElement()->GetElementId();
        }
        else
        {
            associatedPlaneId = GbmpModelViewUtil::GetWorkLevelId(pModelView);
        }
    }
    DBG_WARN_AND_RETURN_FALSE_UNLESS(associatedPlaneId.IsValid(), L"associatedPlaneId无效",L"GDMPLab",L"2024-03-30");

    double bottomOffset(800.0);
    StructureInstancePresetParameterUtils::GetPresetBaseLevelOffset(pDoc, category, categorySecondKey, bottomOffset);

    //设置Z轴定位位置
    WallHoleZPositioningType zPositioningType(WallHoleZPositioningType::Center);
    StructureInstancePresetParameterUtils::GetPresetZPositioningType(pDoc, category, categorySecondKey, zPositioningType);

    input.Document = pDoc;
    input.FamilyId = familyId;
    input.InstanceTypeId = instanceTypeId;
    input.AssociatedPlaneId = associatedPlaneId;
    input.AssociatedPlaneOffset = bottomOffset;
    input.ZPositioningType = zPositioningType;

    return true;
}

bool StructureInstanceCmdUtils::GenerateStructureRoofInput(IDocument* pDoc, IModelView* pModelView,
    const UniIdentity& category, Int32 categorySecondKey, ElementId familyId, ElementId instanceTypeId,
    StructureRoofInput& input)
{
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pDoc, L"pDoc为空",L"GDMPLab",L"2024-03-30");
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pModelView, L"pModelView为空",L"GDMPLab",L"2024-03-30");

    ElementId associatedPlaneId = GbmpModelViewUtil::GetWorkLevelId(pModelView);
    StructureInstancePresetParameterUtils::GetPresetTopLevel(pDoc, category, categorySecondKey, associatedPlaneId);
    DBG_WARN_AND_RETURN_FALSE_UNLESS(associatedPlaneId.IsValid(), L"associatedPlaneId无效",L"GDMPLab",L"2024-03-30");

    input.Document = pDoc;
    input.FamilyId = familyId;
    input.InstanceTypeId = instanceTypeId;
    input.AssociatedPlaneId = associatedPlaneId;
    input.CreationOption = ElementCreationOptions::Normal;
    input.CanBeShared = true;
    input.Visible = true;

    double topOffset(0);
    StructureInstancePresetParameterUtils::GetPresetTopLevelOffset(pDoc, category, categorySecondKey, topOffset);
    input.AssociatedPlaneOffset = topOffset;

    ConcreteStrengthGradeType concreteType(ConcreteStrengthGradeType::CSG_C30);
    StructureInstancePresetParameterUtils::GetPresetConcreteStrengthGradeType(pDoc, category, categorySecondKey, concreteType);
    input.ConcreteType = concreteType;

    return true;
}

bool gcmp::StructureInstanceCmdUtils::AddYPositionInputItemsToDialogNew(const std::wstring& eventId, LineFamilyPositionCurveSideType yPositioningType,
    std::vector<OwnerPtr<gcmp::IControlDefinition>>& inputItems)
{
    // yPositioningType的枚举值 与 RadioButton 的选项值不对应，需要进行下面的对应值转换
    std::wstring defItemValue;
    switch (yPositioningType)
    {
    case LineFamilyPositionCurveSideType::LeftLineFamilyPositionCurveSideType: defItemValue = s_PositionLeft; break;
    case LineFamilyPositionCurveSideType::CenterLineFamilyPositionCurveSideType: defItemValue = s_PositionCenter; break;
    case LineFamilyPositionCurveSideType::RightLineFamilyPositionCurveSideType: defItemValue = s_PositionRight; break;
    default: DBG_WARN(L"yPositioningType的值不在范围内", L"GDMPLab", L"2024-03-30"); defItemValue = s_PositionCenter; break;
    }

    OwnerPtr<IRadioButtonGroupDefinition> opPosTypeGroupDef = IRadioButtonGroupDefinition::Create(eventId, GBMP_TR(L"绘制参照"));
    opPosTypeGroupDef->AddRadioButton(s_PositionLeft, s_PositionLeft, s_PositionLeft);
    opPosTypeGroupDef->AddRadioButton(s_PositionCenter, s_PositionCenter, s_PositionCenter);
    opPosTypeGroupDef->AddRadioButton(s_PositionRight, s_PositionRight, s_PositionRight);
    opPosTypeGroupDef->SetCurrentRadioButton(defItemValue);
    inputItems.push_back(TransferOwnership(opPosTypeGroupDef));

    return true;
}

bool gcmp::StructureInstanceCmdUtils::GetYPositionFromInputEvent(int inputValue, LineFamilyPositionCurveSideType& yPositioningType)
{
    switch (inputValue)
    {
    case 0: yPositioningType = LineFamilyPositionCurveSideType::LeftLineFamilyPositionCurveSideType;   break;
    case 1: yPositioningType = LineFamilyPositionCurveSideType::CenterLineFamilyPositionCurveSideType; break;
    case 2: yPositioningType = LineFamilyPositionCurveSideType::RightLineFamilyPositionCurveSideType;  break;
    default: DBG_WARN(L"对话框的inputValue不在范围内", L"GDMPLab", L"2024-03-30");
        yPositioningType = LineFamilyPositionCurveSideType::CenterLineFamilyPositionCurveSideType;
        return false;
    }

    return true;
}

bool gcmp::StructureInstanceCmdUtils::GetYPositionFromInputEventNew(const std::wstring& inputValue, LineFamilyPositionCurveSideType& yPositioningType)
{
    if (inputValue == s_PositionLeft)
        yPositioningType = LineFamilyPositionCurveSideType::LeftLineFamilyPositionCurveSideType;
    else if (inputValue == s_PositionCenter)
        yPositioningType = LineFamilyPositionCurveSideType::CenterLineFamilyPositionCurveSideType;
    else if (inputValue == s_PositionRight)
        yPositioningType = LineFamilyPositionCurveSideType::RightLineFamilyPositionCurveSideType;
    else
    {
        DBG_WARN(L"对话框的inputValue不在范围内",L"GDMPLab",L"2024-03-30");
        yPositioningType = LineFamilyPositionCurveSideType::CenterLineFamilyPositionCurveSideType;

        return false;
    }

    return true;
}

bool gcmp::StructureInstanceCmdUtils::GetInstancePlacementType(const IFamilyType* pFamilyType, InstancePlacementTypes& posType)
{
    const std::vector<OwnerPtr<IParameter>> parameters = pFamilyType->GetFamilyParameters();
    for (int i = 0; i < (int)parameters.size(); i++)
    {
        if (PARAMETER_UID(InstancePlacementTypeBuiltInParamter).HasSameValue(parameters[i]->GetParameterDefinitionUid()))
        {
            posType = (InstancePlacementTypes)parameters[i]->GetValueAsInt();
            return true;
        }
    }
    return false;
}

bool gcmp::StructureInstanceCmdUtils::GetCategorySubType(const IFamilyType* pFamilyType, int& categorySubType)
{
    const std::vector<OwnerPtr<IParameter>> parameters = pFamilyType->GetFamilyParameters();
    for (int i = 0; i < (int)parameters.size(); i++)
    {
        if (PARAMETER_UID(CategorySubTypeBuiltInParameter).HasSameValue(parameters[i]->GetParameterDefinitionUid()))
        {
            categorySubType = (int)parameters[i]->GetValueAsInt();;
            return true;
        }
    }
    return false;
}

bool StructureInstanceCmdUtils::GenerateStraightStructureStripFoundationInput(IDocument* pDoc, IModelView* pModelView,
    const UniIdentity& category, Int32 categorySecondKey, ElementId familyId, ElementId instanceTypeId,
    StructureStripFoundationInput& input)
{
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pDoc, L"pDoc为空",L"GDMPLab",L"2024-03-30");
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pModelView, L"pModelView为空",L"GDMPLab",L"2024-03-30");

    ElementId associatedPlaneId = GbmpModelViewUtil::GetWorkLevelId(pModelView);
    StructureInstancePresetParameterUtils::GetPresetTopLevel(pDoc, category, categorySecondKey, associatedPlaneId);
    DBG_WARN_AND_RETURN_FALSE_UNLESS(associatedPlaneId.IsValid(), L"associatedPlaneId无效",L"GDMPLab",L"2024-03-30");

    input.Document = pDoc;
    input.AssociatedPlaneId = associatedPlaneId;
    input.FamilyId = familyId;
    input.InstanceTypeId = instanceTypeId;
    input.categoryUid = category;

    double topOffset(0);
    StructureInstancePresetParameterUtils::GetPresetTopLevelOffset(pDoc, category, categorySecondKey, topOffset);
    input.AssociatedPlaneOffset = topOffset;

    StripFoundationZPositioningType zPositioningType(StripFoundationZPositioningType::Top);
    StructureInstancePresetParameterUtils::GetPresetZPositioningType(pDoc, category, categorySecondKey, zPositioningType);
    input.ZPositioningType = zPositioningType;

    ConcreteStrengthGradeType concreteType(ConcreteStrengthGradeType::CSG_C30);
    StructureInstancePresetParameterUtils::GetPresetConcreteStrengthGradeType(pDoc, category, categorySecondKey, concreteType);
    input.ConcreteType = concreteType;

    return true;
}